<template>
  <div class="left">
    <div class="search">
      <el-input placeholder="请输入关键字" v-model="keyword" class="search-tree" size="small" maxlength="100" clearable>
        <el-button slot="append" icon="el-icon-search" size="mini"></el-button>
      </el-input>
    </div>
    <div class="tree-con mt10" v-loading="loading">
      <el-tree
        ref="tree"
        :data="treeData"
        :props="treeProps"
        @node-contextmenu="contextmenuClick"
        @node-click="handleNodeClick"
        node-key="id"
        highlight-current
        size="small"
        :default-expand-all="true"
        :expand-on-click-node="false"
        :filter-node-method="filterNode"
      >
        <span slot-scope="{ node, data }" class="custom-tree-node">
          <span class="m-icon" :class="setClass(node, data)" />
          <span class="node-name" :title="data.name">{{ data.name }}</span>
        </span>
      </el-tree>
      <div v-if="contextMenuShow" ref="contextMenu" class="contextMenu" :style="{ left: left, top: top }">
        <el-button type="text" class="contextMenu-li" @click="handleAdd" :disable="contextmenuNode.level < 3" v-hasPermi="addPermi"
          >新增</el-button
        >
        <el-button type="text" class="contextMenu-li" @click="handleDelete" v-hasPermi="removePermi">删除</el-button>
        <el-button type="text" class="contextMenu-li" @click="handleEdit" v-hasPermi="editPermi">修改</el-button>
        <el-button type="text" class="contextMenu-li" v-if="!addPermi.length&&!editPermi.length&&!removePermi.length">没有权限</el-button>
      </div>
    </div>
    <EditTreeNodeModal :visible.sync="addShow" @onSuccess="onSearch" :type="editType" :handleTreeNode="handleTreeNode" :nodeData="contextmenuData" />
  </div>
</template>
<script>
import EditTreeNodeModal from './EditTreeNode.vue'
import { Message, MessageBox } from 'element-ui'
export default {
  components: { EditTreeNodeModal },
  props: {
    showStat: {
      type: Boolean | undefined,
      default: undefined
    },
    addPermi: {
      type: Array,
      default: () => []
    },
    editPermi: {
      type: Array,
      default: () => []
    },
    removePermi: {
      type: Array,
      default: () => []
    },
    fetchMethod: {
      type: Function,
      default: () => ({})
    },
    deleteMethod: {
      type: Function,
      default: () => ({})
    },
    handleTreeNode: {
      type: Function,
      default: () => ({})
    },
  },
  data() {
    return {
      treeData: [],
      treeProps: {
        children: 'children',
        label: 'name'
      },
      contextMenuShow: false,
      addShow: false,
      left: 0,
      top: 0,
      keyword: '',
      loading: false,
      editType: 'add', // add为新增，edit为修改
      contextmenuData: {},
      contextmenuNode: {},
      selectedData: {} // 当前选中的节点
    }
  },
  mounted() {
    this.addEvent()
    this.onSearch()
  },
  destroyed() {
    window.removeEventListener('click', this.windowClickHandler)
  },
  watch: {
    keyword(val) {
      this.$refs.tree.filter(val)
    }
  },
  methods: {
    addEvent() {
      window.addEventListener('click', this.windowClickHandler)
    },
    windowClickHandler() {
      // if (!this.$refs.contextMenu?.contains(e.target)) {
        this.contextMenuShow = false
      // }
    },
    // 右键
    async contextmenuClick(event, data, node, vnode) {
      event.preventDefault()
      event.stopPropagation()
      this.contextmenuData = data
      this.contextmenuNode = node
      const treeCon = this.$refs.tree
      // 外框位置
      const treeConPos = treeCon.$el.getBoundingClientRect()

      this.contextMenuShow = true
      // 右键弹窗不能超出树结构区域
      let _left = event.clientX - treeConPos.left + 40
      _left = _left > 200 ? 200 : _left
      this.left = _left + 'px'
      let _top = event.clientY - treeConPos.top
      this.top = _top + 'px'
    },
    setClass() {},
    handleNodeClick(data) {
      this.selectedData = data
      this.$refs.tree.setCheckedKeys([data.id])
      this.$emit('updateSelectedNode', data)
    },
    onSearch() {
      this.loading = true
      const data = {
        keyword: this.keyword
      }
      if (this.showStat) {
        data.showStat = this.showStat
      }
      this.fetchMethod(data)
        .then((res) => {
          this.treeData = res.data
          this.$emit('fetched', res.data)
        })
        .finally(() => {
          this.loading = false
        })
    },
    handleAdd() {
      this.editType = 'add'
      this.addShow = true
    },
    handleDelete() {
      MessageBox.confirm(`确认删除节点"${this.contextmenuData.name}"吗？删除后不可恢复`, '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning',
        customClass: 'business-dialog',
        beforeClose: (action, instance, done) => {
          if (action === 'confirm') {
            instance.confirmButtonLoading = true
            this.deleteMethod(this.contextmenuData.id)
              .then((res) => {
                Message.success('删除成功')
                this.onSearch()
              })
              .finally(() => {
                instance.confirmButtonLoading = false
                done()
              })
          } else {
            done()
          }
        }
      })
        .then(() => {})
        .catch((err) => {
          console.log(err)
        })
    },
    handleEdit() {
      this.editType = 'edit'
      this.addShow = true
    },
    filterNode(value, data) {
      if (!value) return true
      return data.name.indexOf(value) !== -1
    }
  }
}
</script>
<style lang="scss" scoped>
@import "~@/assets/styles/editor.scss";
::v-deep .el-tree--highlight-current .el-tree-node.is-current > .el-tree-node__content {
  background-color: #c6d4e4;
}
</style>
